package com.feature.core.mybatis;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.feature.core.domain.PageVo;

@Transactional
public abstract class BaseService<T> implements IService<T> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public boolean saveBatch(Collection<T> entityList, int batchSize) {
		for (T t : entityList) {
			getBaseMapper().insert(t);
		}
		return true;
	}

	@Override
	public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
		for (T t : entityList) {
			saveOrUpdate(t);
		}
		return true;
	}

	@Override
	public boolean updateBatchById(Collection<T> entityList, int batchSize) {
		for (T t : entityList) {
			updateById(t);
		}
		return true;
	}

	@Override
	public boolean saveOrUpdate(T entity) {
		if (getId() == null) {
			throw new UnsupportedOperationException("需实现getId方法");
		}
		return true;
	}

	@Override
	public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
		return getBaseMapper().selectOne(queryWrapper, throwEx);
	}

	@Override
	public Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx) {
		return Optional.ofNullable(getOne(queryWrapper, throwEx));
	}

	@Override
	public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
		List<Map<String, Object>> list = getBaseMapper().selectMaps(queryWrapper);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
		return getOneOpt(queryWrapper, false).map(mapper).orElse(null);
	}

	@Override
	public BaseMapper<T> getBaseMapper() {
		return getSmartBaseMapper();
	}

	public List<T> list(T query) {
		return getSmartBaseMapper().selectList(query);
	}

	public boolean exists(T query) {
		return getSmartBaseMapper().exists(query);
	}

	public Long count(T query) {
		return getSmartBaseMapper().selectCount(query);
	}

	public PageVo<T> list(long curPage, long pageSize, T query) {
		return getSmartBaseMapper().selectPageList(curPage, pageSize, query);
	}

	public T getOne(T query, boolean throwEx) {
		return getSmartBaseMapper().getOne(query, throwEx);
	}

	public T getOne(T query) {
		return getSmartBaseMapper().getOne(query);
	}

	protected abstract SmartBaseMapper<T> getSmartBaseMapper();

	protected Function<T, Long> getId() {
		return null;
	}
}
